package com.etop.basic.dao;

import java.io.Serializable;
import java.util.Collection;
import java.util.List;
import java.util.Map;


import javax.annotation.Resource;

import org.apache.log4j.Logger;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.dao.DataAccessException;
import java.lang.reflect.ParameterizedType;

public class BaseDao<T> implements Serializable {
   protected transient Logger log=Logger.getLogger(this.getClass());
   @Resource
   private SessionFactory sessionFactory;
   private Class<T> persistentClass;
   
   protected Class<T> getCurClass(){
	   if(persistentClass==null){
			this.persistentClass = (Class<T>) ((ParameterizedType) getClass()
					.getGenericSuperclass()).getActualTypeArguments()[0];;
	   }
	   return persistentClass;
   }
   @SuppressWarnings("unchecked")
   public List<T> find(String queryString) throws DataAccessException{
	   //Query query=sessionFactory.getCurrentSession().createQuery(queryString);
	   Query query=createQuery(queryString);
	   query.setCacheable(true);
	   return query.list();
   }
   
   @SuppressWarnings("unchecked")
   public T findUniqueResult(String queryString,Map<String,Object> params) throws DataAccessException{
	   //Query query=sessionFactory.getCurrentSession().createQuery(queryString,params,null,0,-1);
	   //Query query=sessionFactory.getCurrentSession().createQuery("from User user where user.username='admin1'");
	   //query.setParameter(0, );
	   Query query=createQuery(queryString,params,0,-1);
	   return (T)query.uniqueResult();
   }
   
   /*
    * query.setFirstResult():分页查询的起始位置
    * query.setMaxResults():查询结果集的数量
    */
   private Query createQuery(String queryString,
		                    Map<String,Object> params,
		                    int startRow,
		                    int pageSize){
	   Query query=sessionFactory.getCurrentSession().createQuery(queryString);
	   if(params!=null){
		   for(Map.Entry<String, Object> entry :params.entrySet()){
			   String paramName=entry.getKey();
			   Object obj=entry.getValue();
			   log.info("DAO:set param:"+paramName+"with value:"+obj);
			   if(obj instanceof List){
				   query.setParameterList(paramName, (Collection)obj);
			   }else if(obj instanceof Object[]){
				   query.setParameterList(paramName, (Object[])obj);
			   }else {
				   query.setParameter(paramName, obj);
			   }
		   }
	   }
	   query.setCacheable(true);
	   if(pageSize!=-1){
		   query.setFirstResult(startRow).setMaxResults(pageSize);
	   }
	   return query;   
   }
   
   private Query createQuery(String queryString){
	   return createQuery(queryString,null,0,-1);
   }
   private Query createQuery(String queryString,Map<String,Object> params){
	   return createQuery(queryString,params,0,-1);
   }
   public void save(T entity) throws DataAccessException{
	   log.debug("DAO:save entity "+entity.getClass().getSimpleName());
	   sessionFactory.getCurrentSession().save(entity);
   }
   public void saveOrUpdate(T entity) throws DataAccessException{
	   log.debug("DAO:save or update entity" +entity.getClass().getSimpleName());
	   sessionFactory.getCurrentSession().clear();
	   sessionFactory.getCurrentSession().saveOrUpdate(entity);
   }
   public void deleteById(int id){
	   log.debug("DAO: delte by id"+"id:"+id);
	   String queryString="delete from "+getCurClass().getSimpleName()+"where id=?";
	   Query query=sessionFactory.getCurrentSession().createQuery(queryString);
	   query.setParameter(0, id);
	   query.executeUpdate();
	   
   }
}
